<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>碰撞监测</title>
</head>
<body>
<canvas id="canvas">
    your browser not support canvas
</canvas>
<script>
    const WIDTH = 600;
    const HEIGHT = 600;
    var mainBall = {x: 300, y: 300, r: 50};
    var R = 20;
    var color = () => '#' + ('00000' + (Math.random() * 0x1000000 << 0).toString(16)).slice(-6);
    var balls = [];
    var canvas = document.getElementById('canvas'),
        ctx = canvas.getContext('2d');

    canvas.width = WIDTH;
    canvas.height = HEIGHT;

    function init() {
        getBall();
        updateRender();
    }

    function getBall() {
        for (let i = 0; i < 10; i++) {
            balls[i] = {};
            balls[i].x = Math.random() * WIDTH;
            balls[i].y = Math.random() * HEIGHT;
            balls[i].dx = Math.random() * (5 + 1) - 4;
            balls[i].dy = Math.random() * (5 + 1) - 4;
            balls[i].color = color();
        }
    }

    function updateRender() {
        ctx.clearRect(0, 0, WIDTH, HEIGHT);
        ctx.beginPath();
        ctx.arc(mainBall.x, mainBall.y, mainBall.r, 0, Math.PI * 2);
        ctx.fillStyle = 'blue';
        ctx.fill();

        balls.forEach(b => {
            boundary(b);
            ballTouch(b);
            ctx.beginPath();
            ctx.arc(b.x, b.y, R, 0, Math.PI * 2);
            ctx.fillStyle = b.color;
            ctx.fill();
        });

        requestAnimationFrame(updateRender);
    }

    function ballTouch(ball) {
        let dx = ball.x - mainBall.x;
        let dy = ball.y - mainBall.y;
        var dist = Math.sqrt(dx * dx + dy * dy);//利用勾股定理求两个圆心之间的距离
        var min_dist = mainBall.r + R;//两个圆心之间最短距离
        if (dist < min_dist) {
            var angle = Math.atan2(dy, dx);//返回的是原点至点(x,y)的方位角，即与 x 轴的夹角
            var targetX = mainBall.x + Math.cos(angle) * min_dist, //根据夹角计算撞击后的坐标
                targetY = mainBall.y + Math.sin(angle) * min_dist;
            ball.dx += (targetX - ball.x) * 0.03;//根据撞击后的坐标差计算撞击后方向,速度发生的变化
            ball.dy += (targetY - ball.y) * 0.03;
        }
    }

    function boundary(b) {
        b.x = b.x + b.dx;
        b.y = b.y + b.dy;

        if (b.x + R > WIDTH) {
            b.x = WIDTH - R;
            b.dx *= -1;
        }

        if (b.x - R < 0) {
            b.x = R;
            b.dx *= -1;
        }

        if (b.y + R > HEIGHT) {
            b.y = HEIGHT - R;
            b.dy *= -1 * 0.85;
        }

        if (b.y - R < 0) {
            b.y = R;
            b.dy *= -1 * 0.85;
        }
    }

    window.onload = init;

</script>
</body>
</html>